/* Copyright (c) 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.orkut.client.api.samples.greetings.server.servlets;

import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.Transform;
import com.google.appengine.api.images.ImagesService.OutputEncoding;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.orkut.client.api.samples.greetings.shared.CommonConstants;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.URL;

/**
 * Scales down images shown in scraps and the width of scraps is limited.
 *
 * @author Shishir Birmiwal
 */
@Singleton
public class ImageServlet extends HttpServlet {

  private static final int MAX_IMG_WIDTH = 534;
  private static final int HTTP_NOT_OK_THRESH = 300;
  private static final String CONTENT_TYPE = "Content-Type";
  private static final String CONTENT_LENGTH = "Content-Length";
  private final URLFetchService urlFetchService;
  private final ImagesService imgService;

  @Inject
  public ImageServlet(URLFetchService urlFetchService,
      ImagesService imgService) {
    this.urlFetchService = urlFetchService;
    this.imgService = imgService;
  }

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    String imgUrl = req.getParameter(CommonConstants.IMG_URL_PARAM);
    URL url = new URL(imgUrl);
    HTTPResponse imgResponse = urlFetchService.fetch(url);
    if (imgResponse.getResponseCode() >= HTTP_NOT_OK_THRESH) {
      resp.sendError(imgResponse.getResponseCode(), "Error while fetching original image");
    }
    byte[] imgBytes = imgResponse.getContent();
    Image image = ImagesServiceFactory.makeImage(imgBytes);
    int targetWidth = getTargetWidth(req);
    if (image.getWidth() > targetWidth) {
      Transform resize = ImagesServiceFactory.makeResize(targetWidth,
          (image.getHeight() * image.getWidth()) / targetWidth);
      image = imgService.applyTransform(resize, image, OutputEncoding.JPEG);
    }
    for (HTTPHeader header : imgResponse.getHeaders()) {
      if (CONTENT_TYPE.equals(header.getName()) || CONTENT_LENGTH.equals(header.getName())) {
        continue;
      }
      resp.addHeader(header.getName(), header.getValue());
    }
    resp.addHeader(CONTENT_TYPE, getContentType(image));
    BufferedOutputStream outputStream = new BufferedOutputStream(resp.getOutputStream());
    outputStream.write(image.getImageData());
    outputStream.flush();
    outputStream.close();
  }

  private String getContentType(Image image) {
    return "image/" + image.getFormat().toString().toLowerCase();
  }

  private int getTargetWidth(HttpServletRequest req) {
    return MAX_IMG_WIDTH;
  }
}
